package cn.bigcontainer.alt.meta.service.impl;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import javax.annotation.Resource;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import cn.bigcontainer.alt.common.util.WoKit;
import cn.bigcontainer.alt.meta.dto.MDictionaryDto;
import cn.bigcontainer.alt.meta.mapper.MDictionaryMapper;
import cn.bigcontainer.alt.meta.po.MDictionary;
import cn.bigcontainer.alt.meta.service.MDictionaryService;
import lombok.extern.slf4j.Slf4j;

/**
 * @author jiaod
 *
 */
@Service
@Transactional
@Slf4j
public class MDictionaryServiceImpl implements MDictionaryService {

	@Resource
	private MDictionaryMapper dictionaryMapper;

	@Cacheable(cacheNames = "dictionary")
	public List<MDictionary> queryDictionaries(String type) {
		return dictionaryMapper.selectList(new QueryWrapper<MDictionary>().eq("type", type).orderByAsc("value"));
	}

	@Override
	public List<MDictionaryDto> getDictionaries(String type) {
		List<MDictionary> list = queryDictionaries(type);
		return WoKit.getDtos(MDictionaryDto.class, list);
	}

	private Optional<MDictionaryDto> getDictionaryOptional(String type, String value) {
		return getDictionaries(type).stream().filter(d -> d.getValue().equals(value)).findFirst();
	}
	
	@Override
	public MDictionaryDto getDictionary(String type, String value) {
		Optional<MDictionaryDto> findFirst = getDictionaryOptional(type, value);
		if (findFirst.isPresent()) {
			return findFirst.get();
		}
		return null;
	}

	@Override
	public String getDictionaryValue(String type, String names) {
		if (WoKit.isEmpty(names)) {
			return null;
		}
		String[] nameArray = names.split(",");
		String valueString = null;
		for (String nameString : nameArray) {
			Optional<MDictionaryDto> findFirst = getDictionaries(type).stream().filter(d -> d.getName().equals(nameString)).findFirst();
			if (findFirst.isPresent()) {
				if (valueString == null) {
					valueString = findFirst.get().getValue();
				} else {
					valueString += "," + findFirst.get().getValue();
				}
			} else {
				if (valueString == null) {
					valueString = nameString;
				} else {
					valueString += "," + nameString;
				}
			}
		}
		return valueString;
	}

	@Override
	public String getSystemValue(String names) {
		return getDictionaryValue("system", names);
	}

//	@Override
//	public Long getSystemLongValue(String names) {
//		return getSystemLongValue(names, 0L);
//	}

	@Override
	public Long getSystemLongValue(String names, Long defaultValue) {
		String value = getSystemValue(names);
		if (WoKit.isEmpty(value)) {
			return defaultValue;
		}
		return Long.valueOf(value);
	}

	@Override
	public String getDictionaryName(String type, String value) {
		if (WoKit.isEmpty(value)) {
			return null;
		}
		String[] vals = value.split(",");
		String nameString = null;
		for (String valString : vals) {
			Optional<MDictionaryDto> findFirst = getDictionaryOptional(type, valString);
			if (findFirst.isPresent()) {
				if (nameString == null) {
					nameString = findFirst.get().getName();
				} else {
					nameString += "," + findFirst.get().getName();
				}
			} else {
				if (nameString == null) {
					nameString = valString;
				} else {
					nameString += "," + valString;
				}
			}
		}
		return nameString;
	}

	@Override
	public void createOrReplaceDictionaries(Map<String, String> keyValues, String type, String typeName) {
		dictionaryMapper.delete(new QueryWrapper<MDictionary>().eq("type", type));
		keyValues.keySet().forEach(k -> {
			MDictionary dictionary = new MDictionary();
			dictionary.setValue(k);
			dictionary.setName(keyValues.get(k));
			dictionary.setType(type);
			if (!WoKit.isEmpty(typeName)) {
				dictionary.getData().put("typeName", typeName);
			}
			dictionaryMapper.insert(dictionary);
		});
	}

}
